package cz.muni.fi.pv112.cranesimulator.gui;

import com.jogamp.opengl.util.Animator;
import cz.muni.fi.pv112.cranesimulator.gui.listeners.OpenGlListener;
import java.awt.event.MouseEvent;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLJPanel;
import javax.swing.JOptionPane;

import static java.awt.EventQueue.invokeLater;
import static javax.media.opengl.GLProfile.get;

public class MainWindow extends javax.swing.JFrame {

    private static final long serialVersionUID = 1L;

    private final GLJPanel glPanel;
    private final GLProfile profile = get(GLProfile.GL2);
    private final OpenGlListener openGlListener;

    private final ControlsDialog controlsDialog = new ControlsDialog(this, true);

    /**
     * Creates new form MainWindow
     */
    public MainWindow() {
        initComponents();

        setLocationRelativeTo(null);

        final GLCapabilities glCapabilities = new GLCapabilities(profile);

        setAntialiasing(glCapabilities);

        // vytvori sa viditelny panel na ktorom sa bude zobrazovat nas graficky vystup
        glPanel = new GLJPanel(glCapabilities);

        openGlListener = new OpenGlListener();

        // tento panel sa umiestni na hlavne okno aplikacie
        add(glPanel);

        // rozmery glPanela sa nastavia tak, aby sa zhodovali s rozmermi hlavneho okna
        glPanel.setSize(getWidth() - getInsets().left - getInsets().right,
                getHeight() - getInsets().top - getInsets().bottom);

        // k glPanelu pripojime OpenGLListener, aby sme mohli reagovat na udalosti
        // generovane tymto panelom
        glPanel.addGLEventListener(openGlListener);
        glPanel.addKeyListener(openGlListener);

        startWindowAnimator();
    }

    private void setAntialiasing(GLCapabilities glCapabilities) {

        if (JOptionPane.showConfirmDialog(this,
                "Do you want to enable antialiasing ?", "Question",
                JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) {

            glCapabilities.setSampleBuffers(true);
            glCapabilities.setNumSamples(4);
            glCapabilities.setAccumAlphaBits(16);
            glCapabilities.setAccumBlueBits(16);
            glCapabilities.setAccumGreenBits(16);
            glCapabilities.setAccumRedBits(16);
        }
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        applicationMenuBar = new javax.swing.JMenuBar();
        fileMenu = new javax.swing.JMenu();
        exitMenuItem = new javax.swing.JMenuItem();
        optionsMenu = new javax.swing.JMenu();
        controlsMenuItem = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Crane simulator");
        addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                formMouseDragged(evt);
            }
        });
        addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                formMousePressed(evt);
            }
        });
        addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentResized(java.awt.event.ComponentEvent evt) {
                formComponentResized(evt);
            }
        });
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });

        fileMenu.setText("File");

        exitMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_E, java.awt.event.InputEvent.CTRL_MASK));
        exitMenuItem.setIcon(new javax.swing.ImageIcon(getClass().getResource("/cz/muni/fi/pv112/cranesimulator/resources/menu/icons/App-shutdown-icon.png"))); // NOI18N
        exitMenuItem.setText("Exit");
        exitMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exitMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(exitMenuItem);

        applicationMenuBar.add(fileMenu);

        optionsMenu.setText("Options");

        controlsMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_MASK));
        controlsMenuItem.setText("Controls");
        controlsMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                controlsMenuItemActionPerformed(evt);
            }
        });
        optionsMenu.add(controlsMenuItem);

        applicationMenuBar.add(optionsMenu);

        setJMenuBar(applicationMenuBar);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 640, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 459, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    // zmena velkosti okna
    private void formComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentResized
        if (glPanel != null) {
            
            glPanel.setSize(getWidth() - getInsets().left - getInsets().right,
                    getHeight() - getInsets().top - getInsets().bottom);
        }
    }//GEN-LAST:event_formComponentResized

    private void formMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseDragged
        openGlListener.getSceneHandler().processMouseInput(evt,
                MouseEvent.MOUSE_DRAGGED);
//        glPanel.display();
    }//GEN-LAST:event_formMouseDragged

    private void formMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMousePressed
        openGlListener.getSceneHandler().processMouseInput(evt,
                MouseEvent.MOUSE_PRESSED);
    }//GEN-LAST:event_formMousePressed

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        if (glPanel.getAnimator().isStarted()) {

            glPanel.getAnimator().stop();
        }
    }//GEN-LAST:event_formWindowClosing

    private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed
        System.exit(0);
    }//GEN-LAST:event_exitMenuItemActionPerformed

    private void controlsMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_controlsMenuItemActionPerformed
        controlsDialog.showDialog();
    }//GEN-LAST:event_controlsMenuItemActionPerformed

    private void startWindowAnimator() {
        Animator animator = new Animator(glPanel);
        animator.start();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {

        /*
         * Create and display the form
         */
        invokeLater(() -> {
            new MainWindow().setVisible(true);
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuBar applicationMenuBar;
    private javax.swing.JMenuItem controlsMenuItem;
    private javax.swing.JMenuItem exitMenuItem;
    private javax.swing.JMenu fileMenu;
    private javax.swing.JMenu optionsMenu;
    // End of variables declaration//GEN-END:variables
}
